package com.ttbj.product.yitong.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.gson.reflect.TypeToken;
import com.ttbj.api.dto.CostSharingDto;
import com.ttbj.api.dto.CutPayListData;
import com.ttbj.api.yitong.CutPayService;
import com.ttbj.api.yitong.YTFinancialService;
import com.ttbj.constant.YtRespCodeEnum;
import com.ttbj.core.util.CommUtil;
import com.ttbj.core.util.CurrencyUtils;
import com.ttbj.core.util.JsonUtil;
import com.ttbj.core.util.MarkNumUtil;
import com.ttbj.costsharing.dao.CostSharingConfigMapper;
import com.ttbj.costsharing.dao.CostSharingMapper;
import com.ttbj.cutpaycost.dao.CutPayCostMapper;
import com.ttbj.product.bean.CpQueryData;
import com.ttbj.product.util.PropertiesUtil;
import com.ttbj.ytpay.dao.YtPayMapper;


@Service("cutPayService")
public class CutPayServiceImpl implements CutPayService{
	
//	@Autowired
//	private OrderMapper orderMapper;
//	@Autowired
//	private WebOrderMapper webOrderMapper;
	@Autowired
	private CostSharingConfigMapper costSharingConfigMapper;
	@Autowired
	private YTFinancialService ytFinancialService;
	@Autowired
	private CostSharingMapper costSharingMapper;
	@Autowired
	private CutPayCostMapper cutPayCostMapper;
	@Autowired
	private YtPayMapper ytPayMapper;
	
	private static final Logger logger = LoggerFactory.getLogger(CutPayServiceImpl.class);
	
	private static final String PLATFORM_TYPE = "A";	//平台类型
	private static final String DRIVER_TYPE = "B";	//司机类型
	private static final String COMMNUM_TYPE = "C";	//企业类型
	
	@Override
	@Transactional
	public Map<String, String> orderCutPay(String paymentOrderNo, String orderNum, String amount) throws Exception {
//		String platFormAccountNo = null;	//平台账户号
//		String driverAccountNo = null;	//短运司机账户号
//		String comnumAccountNo = null;	//物流企业账户号
//		CostSharingConfig config = null;
//		List<Object> objects = new ArrayList<>();
//		String driverNum = null;	//获取司机编号
//		String driverName = null;	//司机账户名
//		String commnumNum = null;	//物流企业编号
//		String comnumName = null;	//物流企业名称
//		String platFormNum = null;
//		String platFormName = PropertiesUtil.getInstance().getValue("platform_name");	//平台的名称
//		String platFormAccount = "0.00";	//平台需要分账的金额
//		String driverAccount = "0.00";	//司机需要分账的金额
//		String commnumAccount = "0.00";	//公司需要分账的金额
//		String addiData = null;
//		Map<String, String> map = new HashMap<>();
//		//如果传来的订单号包含WEB字符，说明是网络订单
//		if ((int) StringUtils.indexOf(orderNum, "WEB") != -1) {
//			//通过网络订单号，查询出账户号，目前是：平台，短运司机，物流企业
//			WebOrderDto webOrderDto = this.webOrderMapper.queryWebOrderAccountByNum(orderNum);
//			platFormAccountNo = webOrderDto.getPlatFormAccountNo();
//			driverAccountNo = webOrderDto.getDriver().getDriverAccountNo();
//			comnumAccountNo = webOrderDto.getCompany().getComnumAccountNo();
//			driverNum = webOrderDto.getDriver().getDriverNum();
//			driverName = webOrderDto.getDriver().getDriverName();
//			commnumNum = webOrderDto.getCompany().getComnumNum();
//			comnumName = webOrderDto.getCompany().getComnumName();
//			platFormNum = webOrderDto.getPlatFormNum();
//			//查询短运配置分成信息
//			config = this.costSharingConfigMapper.queryCostSharingByType(1);
//		}else if ((int) StringUtils.indexOf(orderNum, "OD") != -1) {
//			//通过订单号，查询出账户号，目前是：平台，短运司机，物流企业
//			OrderDto orderDto = this.orderMapper.queryOrderAccountByNum(orderNum);
//			platFormAccountNo = orderDto.getPlatFormAccountNo();
//			driverAccountNo = orderDto.getDriverAccountNo();
//			comnumAccountNo = orderDto.getComnumAccountNo();
//			driverNum = orderDto.getOrderDriver();
//			driverName = orderDto.getDriverName();
//			commnumNum = orderDto.getComnumNum();
//			comnumName = orderDto.getComnumName();
//			platFormNum = orderDto.getPlatFormNum();
//			//查询长运配置分成信息
//			config = this.costSharingConfigMapper.queryCostSharingByType(2);
//		}
//		logger.info("平台账户号：{}，司机账户号：{}，企业账户号：{}", platFormAccountNo, driverAccountNo, comnumAccountNo);
//		//将总金额转换为元
//		BigDecimal amountCount = CurrencyUtils.toBigDecimal(CommUtil.changeF2Y(amount));
//		logger.info("转换成元后的总金额：{}", amountCount);
//		//将每一个分成比例转换为BigDecimal类型
//		BigDecimal platFormCost = BigDecimal.valueOf(config.getPlatformCostSharing()/100);
//		BigDecimal driverCost = BigDecimal.valueOf(config.getDriverCostSharing()/100);
//		BigDecimal comnumCost = BigDecimal.valueOf(config.getCompanyCostSharing()/100);
//		//金额和比例进行相乘，得到每一个的金额
//		//判断分成配置是否是0，如果非0则进行计算
//		if (platFormCost.compareTo(BigDecimal.ZERO) != 0 && StringUtils.isNotBlank(platFormAccountNo)) {
//			platFormAccount = CurrencyUtils.multiply(amountCount, platFormCost, 2).toString();
//			addiData = platFormName + "|" + platFormNum + "|" + PLATFORM_TYPE;	//平台名和平台编号和标识符组成附加数据
//			CutPayListData platFormdata = new CutPayListData(MarkNumUtil.getNo("CP"), platFormAccountNo, platFormAccount, addiData);
//			objects.add(platFormdata);
//			logger.info("平台分成金额：{}", platFormAccount);
//		}
//		if (driverCost.compareTo(BigDecimal.ZERO) != 0 && StringUtils.isNotBlank(driverAccountNo)) {
//			driverAccount = CurrencyUtils.multiply(amountCount, driverCost, 2).toString();
//			addiData = driverName + "|" + driverNum + "|" + DRIVER_TYPE;	//司机真实姓名和司机编号和标识符组成附加数据
//			CutPayListData driverdata = new CutPayListData(MarkNumUtil.getNo("CP"), driverAccountNo, driverAccount, addiData);
//			objects.add(driverdata);
//			logger.info("司机分成金额：{}", driverAccount);
//		}
//		if (comnumCost.compareTo(BigDecimal.ZERO) != 0 && StringUtils.isNotBlank(comnumAccountNo)) {
//			commnumAccount = CurrencyUtils.multiply(amountCount, comnumCost, 2).toString();
//			addiData = comnumName + "|" + commnumNum + "|" + COMMNUM_TYPE;	//企业名称和企业编号和标识符组成附加数据
//			CutPayListData comnumdata = new CutPayListData(MarkNumUtil.getNo("CP"), comnumAccountNo, commnumAccount, addiData);
//			objects.add(comnumdata);
//			logger.info("物流企业分成金额：{}", commnumAccount);
//		}
//		//如果网关支付订单号为null，通过商户订单号（merOrderNum）查询支付网关订单号（orderId）
//		if (null == paymentOrderNo) {
//			paymentOrderNo = this.ytPayMapper.queryOrderIdByMerOrderNum(orderNum);
//		}
//		//如果objects中没有任何元素，则不进行任何分账，直接返回
//		if (objects == null || objects.isEmpty()) {
//			map.put("status", "0");
//			map.put("retInfo", "分账请求列表中，金额都为0或都无账户号，无法分账");
//			return map;
//		}
//		//执行分账，并获取结果
//		Map<String, String> resultMap = this.ytFinancialService.getCutPayResult(paymentOrderNo, objects, 20, "cutpay");
//		logger.info("返回的resultMap是{}", resultMap);
//		//保存数据：不管成功或者异常的分账信息都保存，后续进行处理异常的分账信息
//		map = savePayMentInfo(paymentOrderNo, orderNum, resultMap, driverNum,
//				commnumNum, amountCount.toString(), platFormAccount, driverAccount, commnumAccount);
//		return map;
		return null;
	}
	
	
	private Map<String, String> savePayMentInfo(String paymentOrderNo, String orderNum, Map<String, String> resultMap, 
			String driverNum, String comnumNum, String aomount, String platFormAccount, String driverAccount, String commnumAccount) throws Exception {
		//获取分账返回的状态
		String status = resultMap.get("status");
		//分账响应信息
		String retInfo = null;
		//分账响应代码
		String retCode = null;
		String datasJson = null;
		Integer costSharingType = 1;	//短运司机为1，长运为2
		List<CutPayListData> datas = null;
		CostSharingDto costSharing = new CostSharingDto();
		Map<String, String> map = new HashMap<>();
		//如果是0的话，说明是失败，分割字符串获取失败信息
		if(status.equals("0")) {
			retInfo = resultMap.get("data").split("\\|")[1];
			retCode = resultMap.get("data").split("\\|")[2];
			//如果返回码为BP001F(待分账余额不足)或BP004F(分账操作过于频繁)或BP005F(分账失败)或S0000F(受理失败)
			//则把请求的json字符串存入数据库，用于直接再次请求分账参数
			if (retCode.equals(YtRespCodeEnum.BP001F) || retCode.equals(YtRespCodeEnum.BP004F) || 
					retCode.equals(YtRespCodeEnum.BP005F) || retCode.equals(YtRespCodeEnum.S0000F)) {
				datasJson = resultMap.get("reqJson");
				//放入CostSharingDto对象中，下面保存到数据库中
				costSharing.setData(datasJson);
			}
		}else if (status.equals("1")) {
			retInfo = "受理成功";
			retCode = "S0000S";
			datas = getDatas(resultMap);	//把分账成功返回的信息转换为List
		}
		costSharing.setOrderNum(orderNum);
		costSharing.setPaymentOrderNo(paymentOrderNo);
		costSharing.setDriverNum(driverNum);
		costSharing.setCompanyNum(comnumNum);
		costSharing.setWebCarriage(aomount);
		costSharing.setPlatFormCostSharing(platFormAccount);
		costSharing.setCompanyCostSharing(commnumAccount);
		costSharing.setDriverCostSharing(driverAccount);
		costSharing.setRetInfo(retInfo);
		costSharing.setRetCode(retCode);
		costSharing.setStatus(status);
		costSharing.setInsTime(new Date());
		//如果是od开头的订单则为长运司机
		if ((int) StringUtils.indexOf(orderNum, "OD") != -1) {
			costSharingType = 2;
		}
		costSharing.setCostSharingType(costSharingType);
		//增加分账信息
		int i = this.costSharingMapper.insertCostSharingInfo(costSharing);
		if (i == 0) {
			logger.info("添加分账信息失败！");
		}
		//如果datas不为null，则说明分账成功，并解析成List，使用List保存到数据库
		if (null != datas && datas.size() > 0) {
			//List保存到数据库
			int m = this.cutPayCostMapper.insertCutPayCostInfo(paymentOrderNo, datas);
			if (m == 0) {
				logger.info("添加分账详细信息失败");
			}
		}
		map.put("status", status);
		map.put("retInfo", retInfo);
		map.put("retCode", retCode);
		return map;
	}

	private List<CutPayListData> getDatas(Map<String, String> resultMap) throws Exception{
		String aesJsonStr = resultMap.get("data");	//获取成功后返回的json字符串，字符串中包含两个data节点
		//获取第一个data节点的json字符串
		String fData = JsonUtil.getJsonStrByNode(aesJsonStr, "data");
		//把第二个data节点中数组对象转换为List
		List<CutPayListData> datas = JsonUtil.jsonToListBean(fData, "data", new TypeToken<ArrayList<CutPayListData>>(){}.getType());
		//分账成功受理后，进行分账查询，查询出子账户分账状态，并一块保存到数据库中
		for (int i = 0; i < datas.size(); i++) {
			String[] addiData = datas.get(i).getAddiData().split("\\|");
			String orderNo = datas.get(i).getTransNo();	//获取分账订单号（分账系统订单号）
			String accountNo = datas.get(i).getAccountNo();	//获取账户号
			CpQueryData data = new CpQueryData(orderNo, accountNo);
			//使用分账查询，并获取返回结果
			Map<String, String> map = this.ytFinancialService.getYTFinancialResult(data, 20, "cp_query");
			//分账查询
			if (map.get("status").equals("1")) {
				//获取data节点的json字符串转换为bean
				CpQueryData cQueryData = (CpQueryData) JsonUtil.jsonToBean(map.get("data"), "data", CpQueryData.class);
				datas.get(i).setStatus(cQueryData.getStatus());
			}else {	//如果受理失败
				datas.get(i).setStatus("04");	//设置为04：处理中
			}
			datas.get(i).setCpName(addiData[0]);	//设置分账人或者企业的名
			datas.get(i).setCpNum(addiData[1]);	//分账人或者企业的编号
			datas.get(i).setCpType(addiData[2]);	//分账类型：A平台，B司机，C企业
		}
		logger.info("分账成功后需要保存的datas，转为json格式：{}", JsonUtil.beanToJson(datas));
		return datas;
	}

	@Override
	@Transactional
	public Map<String, String> againOrderCutPay(String paymentOrderNo, List<Object> data, String datasJson) throws Exception {
		Map<String, String> resultMap = null;
		//分账响应信息
		String retInfo = null;
		//分账响应代码
		String retCode = null;
		//如果是参数正常，网络正常，出现了分账失败，则datasJson有值
		if (null != datasJson && StringUtils.isNotBlank(paymentOrderNo)) {
			List<CutPayListData> listDatas = 
						JsonUtil.jsonToListBean(datasJson, "data", new TypeToken<ArrayList<CutPayListData>>() {}.getType());
			List<Object> objects = new ArrayList<>();
			//每次请求的时候orderNo都不能一样(不管什么原因失败)，所以给orderNo分配新的编号
			for (CutPayListData cutPayListData : listDatas) {
				cutPayListData.setOrderNo(MarkNumUtil.getNo("CP"));
				objects.add(cutPayListData);
			}
			//重新请求分账接口
			resultMap = this.ytFinancialService.getCutPayResult(paymentOrderNo, objects, 20, "cutpay");
		}
		//如果没有datasJson
		if (null == datasJson && StringUtils.isNotBlank(paymentOrderNo) && data.size() > 0) {
			//重新请求分账接口
			resultMap = this.ytFinancialService.getCutPayResult(paymentOrderNo, data, 20, "cutpay");
		}
		String status = resultMap.get("status");	//获取分账状态
		if (status.equals("1")) {	//受理成功
			retInfo = "受理成功";
			retCode = "S0000S";
			CostSharingDto costSharing = new CostSharingDto();
			costSharing.setPaymentOrderNo(paymentOrderNo);
			costSharing.setStatus(status);
			costSharing.setRetInfo(retInfo);
			costSharing.setRetCode(retCode);
			costSharing.setData(null);	//成功后，把data数据置为null
			//进行更新分成的状态信息
			this.costSharingMapper.updateStatusByPaymentOrderNO(costSharing);
			//获取分账后返回的json数据，并转为List<CutPayListData>对象
			List<CutPayListData> datas = getDatas(resultMap);
			//然后保存分账后的信息
			this.cutPayCostMapper.insertCutPayCostInfo(paymentOrderNo, datas);
		}else if (status.equals("0")) {	//受理失败，把失败信息放入Map中
			retInfo = resultMap.get("data").split("\\|")[1];
			retCode = resultMap.get("data").split("\\|")[2];
		}
		resultMap.clear();
		resultMap.put("status", status);
		resultMap.put("retInfo", retInfo);
		resultMap.put("retCode", retCode);
		return resultMap;
	}

}
